/**
  ******************************************************************************
  * @file    main.c
  * @author  ashuai0110
  * @version V2.0
  * @date    2024-09-05
  * @brief   使用举例-伪线程同步方法(信号量,互斥锁,事件集)
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module
  *
  ******************************************************************************
  */

/* 包含头文件-----------------------------------------------------------------*/
#include "bsp.h"

#include "sync_method.h"

/* 私有宏定义-----------------------------------------------------------------*/
#define TEST_EVENT_1               (EVENT_BIT0) /* 测试事件1 */
#define TEST_EVENT_2               (EVENT_BIT1) /* 测试事件2 */

/* 私有类型定义---------------------------------------------------------------*/

/* 私有变量-------------------------------------------------------------------*/
static sync_sem_t testSem; /* 测试信号量实例 */

static uint32_t testInt; /* 测试用临界区 */
static sync_mutex_t testMutex; /* 测试互斥锁实例 */

static sync_event_t testEvent; /* 测试事件集实例 */

/* 全局变量-------------------------------------------------------------------*/

/* 私有函数原型---------------------------------------------------------------*/

/**
  * @brief  临界区写测试
  *
  * @param  value : 写入值
  *
  * @retval None
  */
void critical_write_test(uint32_t value)
{
    /* 获取互斥锁 */
    if(MW_RET_OK == sync_mutex_get(&testMutex))
    {
        testInt = value;
        /* 释放互斥锁 */
        sync_mutex_put(&testMutex);
    }
}

/**
  * @brief  临界区读测试
  *
  * @param  None
  *
  * @retval 目标值
  */
uint32_t critical_read_test(void)
{
    uint32_t temp;
    
    /* 获取互斥锁 */
    if(MW_RET_OK == sync_mutex_get(&testMutex))
    {
        temp = testInt;
        /* 释放互斥锁 */
        sync_mutex_put(&testMutex);
    }
    
    return temp;
}

/**
  * @brief  This function handles SysTick Handler.
  *
  * @param  None
  *
  * @retval None
  */
void SysTick_Handler(void)
{
    static uint16_t cnt = 0;

    cnt++;
    if(0 == cnt % 1000)
    {
        /* 1s周期释放信号量 */
        sync_sem_put(&testSem);

        /* 1s周期写临界区数据 */
        critical_write_test(cnt);

        /* 1s周期释放事件1(事件1触发) */
        sync_event_put(&testEvent, TEST_EVENT_1);
    }
    if(0 == cnt % 5000)
    {
        /* 5s周期释放事件2(事件2触发) */
        sync_event_put(&testEvent, TEST_EVENT_2);
    }
    if(60000 <= cnt) { cnt = 0; }
}

/**
  * @brief  main
  */
int main(int argc, char *argv[])
{
    MW_VER_LOG("example-sync_method", 2, 0, 0);
    
    /* BSP初始化 */
    bsp_init();
    
    /* 信号量初始化 */
    sync_sem_init(&testSem, 0);
    
    /* 互斥锁初始化 */
    sync_mutex_init(&testMutex);
    
    /* 事件集初始化 */
    sync_event_init(&testEvent);

    while(1)
    {
        /* 获取信号量 */
        if(MW_RET_OK == sync_sem_get(&testSem))
        {
            MW_DEBUG_LOG("sem get, read:%d", critical_read_test());
        }
        
#if (1)
        /* 获取事件1与事件2(等待事件1与事件2触发) */
        if(MW_RET_OK == sync_event_get(&testEvent, TEST_EVENT_1 | TEST_EVENT_2, EVENT_AND, EVENT_CLEAR))
        {
            MW_DEBUG_LOG("event1 and event2");
        }
#else
        /* 获取事件1或事件2(等待事件1或事件2触发) */
        if(MW_RET_OK == sync_event_get(&testEvent, TEST_EVENT_1 | TEST_EVENT_2, EVENT_OR, EVENT_CLEAR))
        {
            MW_DEBUG_LOG("event1 or event2");
        }
#endif
    }
}

